package org.smart4j.plugin.security;

import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.CachingSecurityManager;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.ShiroFilter;
import org.smart4j.framework.util.ArrayUtil;
import org.smart4j.plugin.security.realm.SmartCustomRealm;
import org.smart4j.plugin.security.realm.SmartJdbcRealm;

/**
 * description: Smart 安全过滤器 
 * @version v1.0
 * @author w
 * @date 2018年11月4日下午8:25:37
 **/
public class SmartSecurityFilter extends ShiroFilter {
	
	@Override
	public void init() throws Exception {
		super.init();
		WebSecurityManager webSecurityManager = super.getSecurityManager();
		// 设置Realm ， 可同时支持多个Realm，并按照先后顺序用逗号分割
		setRealms(webSecurityManager);
		// 设置Cache，可用于减少数据库查询次数，降低I/O访问
		setCache(webSecurityManager);
	}

	
	/**
	 * description: 设置Realm ， 可同时支持多个Realm，并按照先后顺序用逗号分割
	 * @param webSecurityManager
	 * @return void
	 * @version v1.0
	 * @author w
	 * @date 2018年11月4日 下午8:34:56
	 */
	private void setRealms(WebSecurityManager webSecurityManager) {
		// 读取 smart.plugin.security.realms  配置项
		String realms = SecurityConfig.getRealms();
		if( null != realms){
			String[] realmsArray = realms.split(",");
			if (ArrayUtil.isNotEmpty(realmsArray)) {
				// 使Realm具备唯一性与顺序性
				Set<Realm> realmSet = new LinkedHashSet<Realm>();
				for (String securityRealm : realmsArray) {
					if (securityRealm.equalsIgnoreCase(SecurityConstant.REALMS_JDBC)) {
						// 添加基于JDBC 的 Realm，需要配置相关SQL 查询语句
						addJdbcRealm(realmSet);
					} else if (securityRealm.equalsIgnoreCase(SecurityConstant.REALMS_CUSTOM)) {
						// 添加基于定制化的 Realm，需要实现 SmartSecurity 接口
						addCustomRealm(realmSet);
					}
				} 
				RealmSecurityManager realmSecurityManager = (RealmSecurityManager)webSecurityManager;
				realmSecurityManager.setRealms(realmSet);
			}
		}
	}
	
	
	private void addJdbcRealm(Set<Realm> realmSet) {
		// 添加基于自己实现的 JDBC Realm 
		SmartJdbcRealm jdbcRealm = new SmartJdbcRealm();
		realmSet.add(jdbcRealm);
	}


	private void addCustomRealm(Set<Realm> realmSet) {
		// 读取 smart.plugin.security.custom.class 配置项
		SmartSecurity smartSecurity = SecurityConfig.getSmartSecurity();
		// 添加基于自己实现的 customRealm 
		SmartCustomRealm customRealm = new SmartCustomRealm(smartSecurity);
		realmSet.add(customRealm);
	}


	private void setCache(WebSecurityManager webSecurityManager) {
		// 读取 smart.plugin.security.cache 配置项
		if(SecurityConfig.isCacheable()){
			CachingSecurityManager cachingSecurityManager = (CachingSecurityManager)webSecurityManager;
			// 使用基于内存的 cacheManager
			CacheManager cacheManager = new MemoryConstrainedCacheManager();
			cachingSecurityManager.setCacheManager(cacheManager);
		}
	}
	
	
}
